#include "comtraderecord.h"

/*!
 * \file        comtraderecord.cpp
 * \brief       COMTRADE解析
 * \details
 * \mainpage
 * \author      Sivan
 * \email
 * \version
 * \date        2022-07-05
 * \license
 */

#include <QDebug>

ComtradeRecord::ComtradeRecord(QObject *parent)
    : QObject{parent}
{

}

ComtradeRecord::~ComtradeRecord()
{
    m_analogc_ls.clear();
    m_digitac_ls.clear();
    m_dat_ls.clear();
}

bool ComtradeRecord::parse_init(QString cfgfile)
{
    //CFG文件
    m_cfgfile.setFileName(cfgfile);
    //DAT文件
    QString datfile = cfgfile.replace(".cfg", ".dat");
    m_datfile.setFileName(datfile);

    if(!m_cfgfile.open(QIODevice::ReadOnly| QIODevice::Text))
    {
        return false;
    }
    else
    {
        parse_title();
        parse_channel_title();
        parse_analog_channel();
        parse_digital_channel();
        parse_hz();
        parse_freq();
        parse_time();
        parse_type();
        parse_timemult();

        parse_dat();
    }
    return true;
}

void ComtradeRecord::parse_title()
{
    QList<QByteArray> tokens;

    //station_name,rec_dev_id,rev_year
    QByteArray title = m_cfgfile.readLine();

    tokens = title.split(SPLIT_CHAR);

    m_station_name = tokens.value(0);
    m_rec_dev_id = tokens.value(1);
    m_rev_year = tokens.value(2);
    m_rev_year.chop(1);
}

void ComtradeRecord::parse_channel_title()
{
    bool ok = true;

    QList<QByteArray> tokens;
    // TT,##A,##D
    QByteArray line = m_cfgfile.readLine();
    line.chop(1);
    tokens = line.split(SPLIT_CHAR);
    if (tokens.count() != 3)
    {
        qWarning() << "Invalid CFG line: " << line;
        return;
    }

    //TT
    m_totalChannels = tokens.value(0).toInt(&ok);
    if(!ok)
    {
        qWarning() << "Invalid channels count: " << tokens.value(0);
    }
    //##A
    QByteArray analogToken = tokens.value(1);
    analogToken.chop(1);
    m_analogChannels = analogToken.toInt(&ok);
    if (!ok)
    {
        qWarning() << "Invalid analog count: " << tokens.value(1);
        return;
    }
    //##D
    QByteArray digitalToken = tokens.value(2);
    digitalToken.chop(1);
    m_digitalChannels = digitalToken.toInt(&ok);
    if (!ok)
    {
        qWarning() << "Invalid digital count: " << tokens.value(2);
        return;
    }

    if (m_totalChannels != m_digitalChannels + m_analogChannels)
    {
        qWarning() << "Total count not equal to analog + digital (" << m_totalChannels << m_analogChannels << m_digitalChannels << ")";
        return;
    }
}

void ComtradeRecord::parse_analog_channel()
{
    for (int i=0; i<m_analogChannels; i++)
    {
        QByteArray line = m_cfgfile.readLine();
        line.chop(1);
        ComtradeAnalogChannel *channel = new ComtradeAnalogChannel;
        channel->parse_init(line);
        m_analogc_ls.append(channel);
    }
}

void ComtradeRecord::parse_digital_channel()
{
    for (int i=0; i<m_digitalChannels; i++)
    {
        QByteArray line = m_cfgfile.readLine();
        line.chop(1);
        ComtradeDigitalChannel *channel = new ComtradeDigitalChannel;
        channel->parse_init(line);
        m_digitac_ls.append(channel);
    }
}

void ComtradeRecord::parse_hz()
{
    bool ok = true;
    QByteArray line = m_cfgfile.readLine();
    line.chop(1);

    m_lf = line.toInt(&ok);
    if(!ok)
    {
        qWarning() << "Invalid hz " << line;
    }
}

void ComtradeRecord::parse_freq()
{
    bool ok = true;
    QList<QByteArray> tokens;
    QByteArray line = m_cfgfile.readLine();
    line.chop(1);
    m_nartes = line.toInt(&ok);
    if(!ok)
    {
        qWarning() << "Invalid number " << line;
        return;
    }

    for(int i=0; i<m_nartes; i++)
    {
        line = m_cfgfile.readLine();
        line.chop(1);

        tokens = line.split(SPLIT_CHAR);

        int samp = tokens.value(0).toInt();
        int endsamp = tokens.value(1).toInt();

        m_samp.append(samp);
        m_endsamp.append(endsamp);
    }
}

void ComtradeRecord::parse_time()
{
    QByteArray line = m_cfgfile.readLine();
    line.chop(1);
    m_time_s = line;

    line = m_cfgfile.readLine();
    line.chop(1);
    m_time_e = line;
}

void ComtradeRecord::parse_type()
{
    QByteArray line = m_cfgfile.readLine();
    line.chop(1);
    m_ft = line;
}

void ComtradeRecord::parse_timemult()
{
    QByteArray line = m_cfgfile.readLine();
    line.chop(1);
    m_Timemult = line.toDouble();
}

/*!
 * \brief ComtradeRecord::parse_dat 解析DAT文件
 */
void ComtradeRecord::parse_dat()
{
    if(!m_datfile.open(QIODevice::ReadOnly))
    {
        qWarning() << "Data File Error";
    }

    //开关信号字节长度
    int dig_c_len = 0;
    if(m_digitalChannels%16 != 0)
    {
        dig_c_len = 2*(m_digitalChannels/16 + 1);
    }
    else
    {
        dig_c_len = 2*(m_digitalChannels/16);
    }

    qDebug() << "DIG LEN: " << dig_c_len;

    //单条数据的长度
    uint len = 4 + 4 + m_analogChannels*2 + dig_c_len;

    while(!m_datfile.atEnd())
    {
        QByteArray line;
        line.resize(len);

        uint ret = m_datfile.read(line.data(), len);
        if(ret != len)
        {
            qWarning() << "Parse Data Error";
            return;
        }

        ComtradeData *dat = new ComtradeData;
        dat->parse_dat(line, m_analogChannels, dig_c_len);

        m_dat_ls.append(dat);
    }
}

float ComtradeRecord::get_dat(float x, float a, float b)
{
    return (float)(a*x+b);
}



